package com.suduku.view.constant;

import com.suduku.entity.Box;
import com.suduku.view.data.SudoData;
import com.suduku.view.dialog.MessageDialog;
import com.suduku.view.panel.SudoPanel;

import javax.swing.*;
import java.awt.*;
import java.util.List;

public class ViewConstant {

    //设置全局变量，九宫格
    public static JTextField[][] numberFields = new JTextField[9][9];

    public static JPanel[][] numberPanels = new JPanel[9][9];
    public static JTextField[][][] numberLabels = new JTextField[9][9][9];

    public static JButton[] setNum = new JButton[11];

    public static SudoPanel sudoPanel = new SudoPanel();

    public static JButton[] markBut = new JButton[9];

    public static JButton startBut = new JButton("录入数据");
    public static JButton hintBut = new JButton("    提示    ");
    public static JButton randStartBut = new JButton("随机开始");
    public static JButton markAllBut = new JButton("全部标记");
    public static JButton clearMarkBut = new JButton("清除标记");

    public static JLabel calcLabel = new JLabel("                    ");


    public static final Color green = new Color(93, 200, 138);
    public static final Color lightGray = new Color(217, 217, 217);
    public static final Color blue = new Color(102, 183, 255);

    //创建字体，之后所有的字体为该字体
    public static final Font butFont = new Font("方正仿宋简体", Font.BOLD, 16);
    public static final Font font = new Font("方正仿宋简体", Font.BOLD, 25);
    public static final Font zeroFont = new Font("方正仿宋简体", Font.BOLD, 25);
    public static final Font initFont = new Font("微软雅黑", Font.BOLD, 26);
    public static final Font markFont = new Font("方正仿宋简体", Font.BOLD, 16);

    /***
     * 功能描述: 渲染数独区域 <br/>
     *
     */
    public static void refreshSudoPanel() {
        SudoData.sudo.getBoxList().forEach(box -> {
            JTextField field = numberFields[box.getX()][box.getY()];
            for(int n = 0; n < 9; n++) {
                ViewConstant.numberLabels[box.getX()][box.getY()][n].setText("");
            }
            // 初始化的数值
            if(box.isInitNum()) {
                field.setFont(initFont);
                field.setForeground(Color.BLACK);
                field.setText(box.getV() + "");
            } else {
                // 非初始化数值
                field.setFont(zeroFont);
                field.setForeground(Color.BLUE);
                field.setText(box.getV() == 0 ? "" : box.getV() + "");
            }
            field.setBackground(Color.WHITE);
            // 清理面板
            sudoPanel.remove(box.getI());
            // 添加数字
            sudoPanel.add(field, box.getI());
        });
        sudoPanel.repaint();
        sudoPanel.validate();
    }

    public static void focusGained(Box box) {
        SudoData.sudo.getBoxList().forEach(b -> {
            // 如果选中的区域是数字，则点亮相同数字的背板
            if(box.getV() > 0) {
                if(b.getV().equals(box.getV())) {
                    numberFields[b.getX()][b.getY()].setBackground(Color.CYAN);
                } else {
                    numberFields[b.getX()][b.getY()].setBackground(Color.WHITE);
                }
                setMarkBackground(b, box.getV());
            } else {
                // 如果选中的区域不是数字，则将影响方位的背板点亮
                if(b.getX() == box.getX() || b.getY() == box.getY() || b.getG() == box.getG()) {
                    numberFields[b.getX()][b.getY()].setBackground(Color.CYAN);
                    // 设置标记区域
                    setMarkBackground(b, Color.CYAN);
                } else {
                    numberFields[b.getX()][b.getY()].setBackground(Color.WHITE);
                    // 设置标记区域
                    setMarkBackground(b, Color.WHITE);
                }
            }
        });
        // 设置当前选中的背景色
        numberFields[box.getX()][box.getY()].setBackground(Color.RED);
        // 换成红色
        setMarkBackground(box, Color.RED);
        if(box.isInitNum()) {
            // 候选区的按钮不可用
            enableButton(null, false);
        } else {
            enableButton(box.getCList(), box.getV() > 0);
        }
    }

    private static void setMarkBackground(Box box, Color color) {
        Boolean b = SudoData.markMap.get(box.getX() + "" + box.getY());
        if(b != null && b) {
            for(int n = 0; n < 9; n++) {
                numberLabels[box.getX()][box.getY()][n].setBackground(color);
            }
        }
    }

    private static void setMarkBackground(Box box, Integer v) {
        Boolean b = SudoData.markMap.get(box.getX() + "" + box.getY());
        if(b != null && b) {
            for (int n = 0; n < 9; n++) {
                JTextField field = numberLabels[box.getX()][box.getY()][n];
                if(field.getText().equals(v + "")) {
                    field.setBackground(Color.CYAN);
                } else {
                    field.setBackground(Color.WHITE);
                }
            }
        }
    }

    /**
     * 功能描述: 设置候选区按钮 <br/>
     *
     * @param cList     候选数字
     * @param clearFlag 清除按钮是否可用
     */
    public static void enableButton(List<Integer> cList, boolean clearFlag) {
        for (int i = 0; i < 9; i++) {
            ViewConstant.setNum[i].setEnabled(false);
            ViewConstant.markBut[i].setEnabled(false);
        }
        if (cList != null && cList.size() > 0) {
            for (Integer c : cList) {
                ViewConstant.setNum[c - 1].setEnabled(true);
                ViewConstant.markBut[c - 1].setEnabled(true);
            }
        }
        ViewConstant.setNum[10].setEnabled(clearFlag);
    }

    /**
     * 功能描述: 设置单元格确定数字 <br/>
     *
     * @param text 数字
     */
    public static void setNum(String text) {
        if(SudoData.CX > -1 && SudoData.CY > -1) {
            // 操作前备份
            SudoData.backup();
            Box box = SudoData.getByIndex(SudoData.CX * 9 + SudoData.CY);
            box.setVAndClear(Integer.valueOf(text));
            SudoData.sudo.refreshOtherBox(box);
            Boolean b = SudoData.markMap.get(SudoData.CX + "" + SudoData.CY);
            if(b != null && b) {
                // 删除标记
                SudoData.markMap.remove(SudoData.CX + "" + SudoData.CY);
                // 移除标记区域
                int index = SudoData.CX * 9 + SudoData.CY;
                // 清空标记内容
                cleanMarkLabels();
                ViewConstant.sudoPanel.remove(index);
                // 添加标记面板
                ViewConstant.sudoPanel.add(ViewConstant.numberFields[SudoData.CX][SudoData.CY], index);
                // 刷新
                ViewConstant.sudoPanel.validate();
            }
            ViewConstant.numberFields[SudoData.CX][SudoData.CY].setText(text);
            cleanValueLabels(text);
            ViewConstant.focusGained(box);
        }
        // 判断是否完成，如果完成，则提示
        if (SudoData.sudo.isFinish()) {
            new MessageDialog("恭喜你，完成游戏！");
        }
    }

    /**
     * 功能描述: 清理影响范围内相同的数字 <br/>
     */
    private static void cleanValueLabels(String v) {
        Box box = SudoData.getCurrentBox();
        SudoData.sudo.getBoxList().forEach(b -> {
            Boolean f = SudoData.markMap.get(b.getX() + "" + b.getY());
            if(f != null && f) {
                if(b.getX() == box.getX() || b.getY() == box.getY() || b.getG() == box.getG()) {
                    for(int n = 0; n < 9; n++) {
                        JTextField field = ViewConstant.numberLabels[b.getX()][b.getY()][n];
                        if(field.getText().equals(v)) {
                            field.setText("");
                        }
                    }
                }
            }
        });
    }

    /**
     * 功能描述: 清空当前单元格的标记记录 <br/>
     */
    private static void cleanMarkLabels() {
        for(int n = 0; n < 9; n++) {
            ViewConstant.numberLabels[SudoData.CX][SudoData.CY][n].setText("");
        }
    }

    /**
     * 功能描述: 设置单元格标记数字 <br/>
     *
     */
    public static void setMarkNum() {
        if(SudoData.CX > -1 && SudoData.CY > -1) {
            // 添加标记 区域
            SudoData.markMap.putIfAbsent(SudoData.CX + "" + SudoData.CY, true);
            if(SudoData.markMap.get(SudoData.CX + "" + SudoData.CY)) {
                // 移除原来的JTextField
                int index = SudoData.CX * 9 + SudoData.CY;
                ViewConstant.sudoPanel.remove(index);
                // 添加标记面板
                ViewConstant.sudoPanel.add(ViewConstant.numberPanels[SudoData.CX][SudoData.CY], index);
                // 刷新
                ViewConstant.sudoPanel.validate();
            }
            for (int n = 0; n < 9; n++) {
                ViewConstant.numberLabels[SudoData.CX][SudoData.CY][n].setBackground(Color.RED);
            }
        }
    }

}
